package com.fy.config;


import com.fy.utils.StringUtils;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.util.unit.DataSize;
import org.springframework.util.unit.DataUnit;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.MultipartConfigElement;
import java.text.SimpleDateFormat;
import java.util.Date;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //将所有/static/** 访问都映射到classpath:/static/ 目录下
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }

    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();

        //单个文件最大
        factory.setMaxFileSize(DataSize.of(1000, DataUnit.MEGABYTES));
        //设置总上传数据总大小
        factory.setMaxRequestSize(DataSize.of(2000, DataUnit.MEGABYTES));
        return factory.createMultipartConfig();
    }

    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory() {

        // 修改内置的 tomcat 容器配置
        TomcatServletWebServerFactory tomcatServlet = new TomcatServletWebServerFactory();
        tomcatServlet.addConnectorCustomizers(
                connector -> connector.setProperty("relaxedQueryChars", "[]{}")
        );

        return tomcatServlet;
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");
    }

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); //允许任何域名
        corsConfiguration.addAllowedHeader("*"); //允许任何头
        corsConfiguration.addAllowedMethod("*"); //允许任何方法
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); //注册
        return new CorsFilter(source);
    }

    @Bean
    public LoginInterceptor authenticationInterceptor() {
        return new LoginInterceptor();
    }

    /**
     * 添加自定义的Converters和Formatters.
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToDateConverter());
    }

    @Configuration
    public class StringToDateConverter implements Converter<String, Date> {
        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
        private static final String shortDateFormat = "yyyy-MM-dd";
        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
        private static final String shortDateFormat2 = "yyyy/MM/dd";

        @Override
        public Date convert(String source) {
            if (StringUtils.isBlank(source)) {
                return null;
            }
            source = source.trim();
            try {
                SimpleDateFormat formatter;
                if (source.contains("-")) {
                    if (source.contains(":")) {
                        formatter = new SimpleDateFormat(dateFormat);
                    } else {
                        formatter = new SimpleDateFormat(shortDateFormat);
                    }
                    Date dtDate = formatter.parse(source);
                    return dtDate;
                } else if (source.contains("/")) {
                    if (source.contains(":")) {
                        formatter = new SimpleDateFormat(dateFormat2);
                    } else {
                        formatter = new SimpleDateFormat(shortDateFormat2);
                    }
                    Date dtDate = formatter.parse(source);
                    return dtDate;
                }
            } catch (Exception e) {
                throw new RuntimeException(String.format("parser %s to Date fail", source));
            }

            throw new RuntimeException(String.format("parser %s to Date fail", source));

        }
    }
}

